home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 2
/
Deutsche Edition 2.iso
/
mac
/
POWERMAC
/
C64
/
SOURCE
/
BWVic.c
< prev
next >
Wrap
Text File
|
1994-06-06
|
6KB
|
276 lines
/*
Commodore 64 Emulator v0.4 Earle F. Philhower III
Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Processor.h"
#include "Memory.h"
#include "Error.h"
#include "Resources.h"
#include "VIC.h"
/* This FastDraw macro courtesy of Peter Creath <peterc@gnu.ai.mit.edu> */
/* It's much faster than my original "FastDraw" which was a misnomer */
#define FastDraw(a, b, c) \
{ \
thisLine=(char**)&(lineStart[(word)((a)<<3)]); \
theseDefs=(char*)(VICCharDefs+(word)((c)<<3)); \
*(*thisLine++ + b)=*theseDefs++; \
*(*thisLine++ + b)=*theseDefs++; \
*(*thisLine++ + b)=*theseDefs++; \
*(*thisLine++ + b)=*theseDefs++; \
*(*thisLine++ + b)=*theseDefs++; \
*(*thisLine++ + b)=*theseDefs++; \
*(*thisLine++ + b)=*theseDefs++; \
*(*thisLine++ + b)=*theseDefs++; \
}
static byte *lineStart[200];
static Rect leftRect, rightRect, topRect, botRect, sprRect;
static BitMap spriteMap, VICMap, fullMap;
static GrafPtr spriteGraf;
extern Rect bwWindRect, bwFullRect;
static Ptr NewBitMap(BitMap *theBits, Rect *rp)
{
theBits->rowBytes=((rp->right-rp->left+15)/16)*2;
theBits->baseAddr=(Ptr)GetMemory(theBits->rowBytes*(rp->bottom-rp->top));
theBits->bounds=*rp;
return(theBits->baseAddr);
}
int BWVICInitialize()
{
int row;
SetRect(&bwFullRect, 0, 0, 320, 200);
SetRect(&leftRect, 0, 0, 7, 200);
SetRect(&rightRect, 320-8, 0, 320, 200);
SetRect(&topRect, 0, 0, 320, 4);
SetRect(&botRect, 0, 200-4, 320, 200);
SetRect(&sprRect, 0, 0, 24, 21);
BWVICWind=GetNewWindow(kBWVIC, nil, (WindowPtr)-1L);
if (BWVICWind==nil) return(kMissingResource);
SetWRefCon(BWVICWind, kVICWindow);
if (NewBitMap(&spriteMap, &sprRect)==0) return kOutOfMemory;
if (NewBitMap(&VICMap, &bwFullRect)==0) return kOutOfMemory;
if (NewBitMap(&fullMap, &bwFullRect)==0) return kOutOfMemory;
for (row=0; row<200; row++)
lineStart[row]=(byte *)VICMap.baseAddr+40*row;
return(kNoError);
}
void ShowBWVIC()
{
SelectWindow(BWVICWind);
ShowWindow(BWVICWind);
SetPort(BWVICWind);
}
void HideBWVIC()
{
HideWindow(BWVICWind);
}
static void DrawSprites()
{
byte spriteNum, row, *spb0, *spb1, *spb2;
word xpos, ypos, addr0, addr1, addr2;
Rect t;
BitMap saveMap;
CopyBits(&VICMap,&fullMap,&bwFullRect,&bwFullRect,srcCopy,nil);
saveMap = qd.thePort->portBits;
SetPortBits(&spriteMap);
for (spriteNum=0; spriteNum<8; spriteNum++)
if (VICRegister[0x15]&(1<<spriteNum))
{
xpos = (VICRegister[0x00+spriteNum*2]-24);
xpos += (VICRegister[0x10]&(1<<spriteNum))?256:0;
ypos = VICRegister[0x01+spriteNum*2]-50;
t.top=ypos;
t.left=xpos;
t.right=t.left+24+((VICRegister[0x1d]&(1<<spriteNum))?24:0);
t.bottom=t.top+21+((VICRegister[0x17]&(1<<spriteNum))?21:0);
addr0 = VICAddrBase+RAM[VICScreenPage+1016+spriteNum]*64;
addr1=addr0+1;
addr2=addr0+2;
spb0=(byte *)spriteMap.baseAddr;
spb1=spb0+1;
spb2=spb0+2;
for (row=0; row<21; row++)
{
spb0[row<<2]=RAM[addr0+row*3];
spb1[row<<2]=RAM[addr1+row*3];
spb2[row<<2]=RAM[addr2+row*3];
}
CopyBits(&spriteMap,&fullMap,&sprRect,&t,srcOr,nil);
}
SetPortBits(&saveMap);
SetPort(BWVICWind);
}
static void DrawTextScreen(byte total)
{
word chr;
byte row, col;
register char **thisLine;
register char *theseDefs;
BitMap saveMap;
row=col=0;
saveMap=qd.thePort->portBits;
SetPortBits(&VICMap);
if (VICRegister[0x11]&32)
{
/* Draw Hi-Res screen *always* since that only makes sense */
VICCharDefs=RAM+VICAddrBase+((VICRegister[0x18]&8)?8192:0);
for (chr=0; chr<1000; chr++)
{
FastDraw(row,col,chr);
col++;
if (++col>39)
{
col=0;
row++;
}
}
}
else
{
/* Draw the text screen */
if (total)
/* Draw every single character */
for (chr=0; chr<1000; chr++)
{
FastDraw(row,col,RAM[chr+VICScreenPage]);
VICText[chr]=RAM[chr+VICScreenPage];
if (++col>39)
{
col=0;
row++;
}
}
else
for (chr=0;chr<1000;chr++)
{
if (VICText[chr]!=RAM[chr+VICScreenPage])
{
FastDraw(row,col,RAM[chr+VICScreenPage]);
VICText[chr]=RAM[chr+VICScreenPage];
}
if (++col>39)
{
col=0;
row++;
}
}
}
SetPortBits(&saveMap);
}
static void DrawBorders()
{
BitMap saveMap;
saveMap=qd.thePort->portBits;
SetPortBits(&VICMap);
if ((VICRegister[0x16]&8)==0)
{
FillRect(&leftRect, (ConstPatternParam)&qd.black);
FillRect(&rightRect, (ConstPatternParam)&qd.black);
}
if ((VICRegister[0x11]&8)==0)
{
FillRect(&botRect, (ConstPatternParam)&qd.black);
FillRect(&topRect, (ConstPatternParam)&qd.black);
}
SetPortBits(&saveMap);
}
static void CopyTextToScreen()
{
SetPort(BWVICWind);
CopyBits(&VICMap, &(BWVICWind->portBits), &bwFullRect, &bwWindRect, srcCopy, nil);
}
static void CopySpritesToScreen()
{
SetPort(BWVICWind);
CopyBits(&fullMap, &(BWVICWind->portBits), &bwFullRect, &bwWindRect, srcCopy, nil);
}
static void BlankScreen()
{
BitMap saveMap;
saveMap = qd.thePort->portBits;
SetPortBits(&VICMap);
FillRect(&bwFullRect, (PatPtr)&qd.gray);
SetPortBits(&saveMap);
CopyTextToScreen();
}
void BWTotalRedrawVIC()
{
SetPort(BWVICWind);
if ((VICRegister[0x11]&16)==0)
{
BlankScreen();
return;
}
DrawTextScreen(1);
DrawBorders();
if (VICRegister[0x15])
{
DrawSprites();
CopySpritesToScreen();
}
else CopyTextToScreen();
}
void BWRedrawVIC()
{
SetPort(BWVICWind);
if ((VICRegister[0x11]&16)==0)
{
BlankScreen();
return;
}
DrawTextScreen(0);
DrawBorders();
if (VICRegister[0x15])
{
DrawSprites();
CopySpritesToScreen();
}
else CopyTextToScreen();
}